package com.futu.es.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.futu.attraction.domain.City;
import com.futu.attraction.domain.CitySopt;
import com.futu.attraction.service.CityService;
import com.futu.attraction.service.CitySoptService;
import com.futu.common.enums.ApiServiceExceptionEnum;
import com.futu.common.utils.TokenUtils;
import com.futu.common.vo.ResultVo;
import com.futu.es.domain.EsSpot;
import com.futu.es.domain.MangodbSpot;
import com.futu.es.dto.SpotByIdDto;
import com.futu.es.dto.SpotDto;
import com.futu.es.mapper.EsSpotMapper;
import com.futu.es.mapper.MangodbSpotMapper;
import com.futu.es.service.EsSoptService;
import com.futu.es.service.MangodbService;
import com.futu.scenicspot.domain.HPlayProject;
import com.futu.scenicspot.domain.HScenicSpot;
import com.futu.scenicspot.service.HPlayProjectService;
import com.futu.scenicspot.service.HScenicSpotService;
import lombok.extern.slf4j.Slf4j;
import org.dromara.easyes.common.utils.StringUtils;
import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class EsSoptServiceImpl extends ServiceImpl<MangodbSpotMapper, MangodbSpot> implements EsSoptService {

    @Autowired
    private EsSpotMapper esSpotMapper;

    @Autowired
    private HScenicSpotService service;

    @Autowired
    private MangodbService mangodbService;
    @Autowired
    private MangodbServiceImpl mangodbServiceImpl;

    @Autowired
    private HPlayProjectService hPlayProjectService;
    @Autowired
    private RedisTemplate redisTemplate;
    
    @Autowired
    private CityService cityService;
    
    @Autowired
    private CitySoptService citySoptService;

    public boolean checkAndCreateIndex(String indexName) {//索引--相当于表名，用于存储数据
        try {
            // 检查索引是否存在
            boolean exists = esSpotMapper.existsIndex(indexName);

            if (exists) {
                log.info("Index already exists: {}", indexName);
                return true;
            }

            // 索引不存在，创建新索引
            boolean created = esSpotMapper.createIndex(indexName);

            if (created) {
                log.info("Successfully created index: {}", indexName);
            } else {
                log.error("Failed to create index: {}", indexName);
            }

            return created;
        } catch (Exception e) {
            log.error("Error while checking or creating index: {}", indexName, e);
            return false;
        }
    }

    public ResultVo selectSopt(SpotDto dto) {//搜索时出现下拉框

        // 构建查询条件
        LambdaEsQueryWrapper<EsSpot> queryWrapper = new LambdaEsQueryWrapper<>();
        // 动态添加条件
        if (StringUtils.isNotBlank(dto.getName())) {
            // 使用 match 实现模糊匹配
            queryWrapper.match(EsSpot::getName, dto.getName());
        }
        // 分页设置
        // 假设 dto.getPage() 是当前页码，dto.getSize() 是每页数量
        int from = (dto.getPage() - 1) * dto.getSize();
        int size = dto.getSize();
        queryWrapper.from(from).size(size);
        // 执行查询
        List<EsSpot> esSpots = esSpotMapper.selectList(queryWrapper);
        log.info("查询结果：{}", esSpots.size());

        return ResultVo.success(esSpots);
    }

    public ResultVo MysqlInterEs() {{//同步mysql数据到es
        this.checkAndCreateIndex("es_spot");
        log.info("删除es原有数据");
        try {
            // 尝试删除ES数据，即使没有数据也不会抛出异常

            esSpotMapper.delete(new LambdaEsQueryWrapper<>());
            log.info("ES数据删除操作完成");
        } catch (Exception e){
            // 如果删除过程中出现异常（如索引不存在），捕获并继续执行
            log.warn("ES数据删除操作可能失败或无需执行: {}", e.getMessage());}
        List<HScenicSpot> list = service.list();
        List<EsSpot>spotList=new ArrayList<>();

        for (HScenicSpot hScenicSpot : list) {
            EsSpot spot = new EsSpot();
            spot.setId(hScenicSpot.getId());
            spot.setName(hScenicSpot.getName());
            spot.setDescription(hScenicSpot.getDescription());
            spot.setLatitude(hScenicSpot.getLatitude());
            spot.setLongitude(hScenicSpot.getLongitude());
            spot.setPanoramaUrl(hScenicSpot.getPanoramaUrl());
            spot.setCreateTime(hScenicSpot.getCreateTime());
            spot.setUpdateTime(hScenicSpot.getUpdateTime());
            
            // 查询景点所属城市
            QueryWrapper<CitySopt> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("sopt_id", hScenicSpot.getId());
            CitySopt citySopt = citySoptService.getOne(queryWrapper);
            
            if (citySopt != null) {
                // 获取城市信息
                City city = cityService.getById(citySopt.getCityId());
                if (city != null) {
                    // 设置城市名称
                    spot.setCityname(city.getCityName());
                    // 设置地址（城市名 + 景点名）
                    spot.setAddress(city.getProName() + city.getCityName() + hScenicSpot.getName());
                }
            }
            
            // 如果没有找到城市信息，设置默认值
            if (spot.getCityname() == null) {
                spot.setCityname("未知城市");
            }
            if (spot.getAddress() == null) {
                spot.setAddress(spot.getCityname() + spot.getName());
            }
            
            spotList.add(spot);
        }
        log.info("开始同步数据");
        Integer integer = esSpotMapper.insertBatch(spotList);
        log.info("同步数据完成");
        return integer>0?ResultVo.success(ApiServiceExceptionEnum.RESULT_SUCCES):ResultVo.error(ApiServiceExceptionEnum.RESULT_ERROR);
    }}
     //查询景点详情后记录到mongodb
    public ResultVo SelSopt(SpotByIdDto dto) {


            // 1. 参数校验
            if (dto == null || dto.getId() == null) {
                log.warn("查询景点详情并插入MongoDB失败，参数不完整，dto: {}", dto);
                return ResultVo.error(ApiServiceExceptionEnum.RESULT_ERROR); // 假设定义了参数错误的枚举
            }

            try {
                // 2. 查询景点信息
                EsSpot esSpot = esSpotMapper.selectById(dto.getId());
                if (esSpot == null) {
                    log.info("未查询到景点，景点ID：{}", dto.getId());
                    return ResultVo.error(ApiServiceExceptionEnum.DATA_NOT_FOUND); // 数据不存在的枚举
                }

                // 3. 构建要插入MongoDB的对象
                MangodbSpot mangodbSpot = buildMangodbSpot(dto, esSpot);

                // 4. 插入MongoDB
                MangodbSpot insertResult = mangodbService.insert(mangodbSpot);
                if (insertResult == null) {
                    log.error("插入MongoDB失败，插入对象：{}", mangodbSpot);
                    return ResultVo.error(ApiServiceExceptionEnum.INSERT_ERROR); // 插入失败的枚举
                }

                log.info("查询景点并插入MongoDB成功，景点ID：{}，插入结果：{}", dto.getId(), insertResult);
                return ResultVo.success(insertResult);
            } catch (Exception e) {
                log.error("查询景点并插入MongoDB发生异常，dto：{}", dto, e);
                return ResultVo.error(ApiServiceExceptionEnum.SYSTEM_ERROR); // 系统异常的枚举
            }
        }

        /**
         * 构建 MangodbSpot 对象
         */
        private MangodbSpot buildMangodbSpot(SpotByIdDto dto, EsSpot esSpot) {

            MangodbSpot mangodbSpot = new MangodbSpot();
            mangodbSpot.setSpotId(esSpot.getId());
            mangodbSpot.setName(esSpot.getName());
            mangodbSpot.setDescription(esSpot.getDescription());
            mangodbSpot.setUserId(dto.getUserId());
            mangodbSpot.setLatitude(esSpot.getLatitude());
            mangodbSpot.setLongitude(esSpot.getLongitude());
            mangodbSpot.setCreateTime(esSpot.getCreateTime());
            mangodbSpot.setUpdateTime(esSpot.getUpdateTime());
            return mangodbSpot;

        }
    //根据mangodb中的用户最常看的景点进行玩法推荐
    public ResultVo recommend(String token) {
//        if (token == null)
//        {
//            return ResultVo.error(ApiServiceExceptionEnum.USER_NOT_EXISTS);
//        }
//        Long userId = TokenUtils.getUserId(token);
//        MangodbSpot spots = mangodbServiceImpl.findMostVisitedSpots(userId);
//        List<HPlayProject> list = hPlayProjectService.list(new LambdaQueryWrapper<HPlayProject>().eq(HPlayProject::getScenicId, spots.getSpotId()));
//        return list != null ? ResultVo.success(list) : ResultVo.error();

            // 参数校验
            if (token == null) {
                return ResultVo.error(ApiServiceExceptionEnum.USER_NOT_EXISTS);
            }

            // 获取用户ID
            Long userId = TokenUtils.getUserId(token);
            if (userId == null) {
                return ResultVo.error(ApiServiceExceptionEnum.USER_NOT_EXISTS);
            }

            // 获取用户最常访问的景点
            MangodbSpot spot = mangodbServiceImpl.findMostVisitedSpots(userId);
        System.out.println("spot: " + spot);
            if (spot == null || spot.getSpotId() == null) {
                return ResultVo.error("未找到相关景点");
            }

            // 查询景点关联的游玩项目
            List<HPlayProject> projects = hPlayProjectService.list(
                    new LambdaQueryWrapper<HPlayProject>()
                            .eq(HPlayProject::getScenicId, spot.getSpotId())
            );

            return projects != null && !projects.isEmpty()
                    ? ResultVo.success(projects)
                    : ResultVo.error("未找到相关游玩项目");
        }

    }


